<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  
  <meta name="generator" content="Hugo 0.98.0" />

  
  <meta name="description" content="走在通往幸福的路上">
  

  
  <link rel="apple-touch-icon" sizes="180x180" href="https://blog.v5u.win/apple-touch-icon.png">

  
  <link rel="icon" type="image/png" sizes="32x32" href="https://blog.v5u.win/favicon-32x32.png">

  
  <link rel="icon" type="image/png" sizes="16x16" href="https://blog.v5u.win/favicon-16x16.png">

  
  <link rel="manifest" href="https://blog.v5u.win/site.webmanifest">

  
  <link rel="mask-icon" href="https://blog.v5u.win/safari-pinned-tab.svg" color="">

  <meta name="msapplication-TileColor" content="">

  <meta name="theme-color" content="">

  
  <link rel="stylesheet" href="https://blog.v5u.win/css/bootstrap.min.css" />

  
  <title>Go异常处理 | 为吾优</title>
  

  <style>
body {
  min-width: 300px;
}

.custom-navbar {
  margin-bottom: 1em;
  height: 60px;
}

.custom-navbar a {
  display: inline-block; 
  padding: 18px 0;
  margin-right: 1em; 
  font-weight: bold; 
}

.custom-navbar a:hover,
.custom-navbar a:focus {
  text-decoration: none; 
}

@media print {
  .custom-navbar {
    display: none;
  }
}

article {
  padding-bottom: 1em;
}

img {
  max-width: 100%;
}


body {
  background-color: #fff;
}



body {
  color: #212529;
}



a {
  color: #007bff;
}



a:hover,
a:focus {
  color: #0056b3;
}



.custom-navbar {
  background-color: #212529;
}



.custom-navbar a {
  color: rgba(255,255,255,.75);
}



.custom-navbar a:hover,
.custom-navbar a:focus {
  color: rgba(255,255,255,1);
}



.container {
  max-width: 800px;
}





</style>
</head>

<body>
  <nav class="custom-navbar">
  <div class="container">
    
    <a href="/">文章</a>
    
    <a href="/tags/">标签</a>
    
    <a href="/about/">关于</a>
    
    <a href="/index.xml">RSS</a>
    
  </div>
</nav>
  
  <div class="container">
    <article>
      <h1>Go异常处理</h1>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>error的声明</p>
<p>创建一个error</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>error的使用</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<h2 id="异常处理panic">异常处理——panic</h2>
<p>译为运行时恐慌</p>
<p>内建函数<code>panic</code>和<code>recover</code>是天生的一对。前者用于产生运行时恐慌，而后者用于“恢复”它。</p>
<p>不过要注意，<code>recover</code>函数必须要在<code>defer</code>语句中调用才有效。因为一旦有运行时恐慌发生，当前函数以及在调用栈上的所有代码都是失去对流程的控制权。只有<code>defer</code>语句携带的函数中的代码才可能在运行时恐慌迅速向调用栈上层蔓延时“拦截到”它。</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p><code>panic</code>函数。该函数可接受一个<code>interface{}</code>类型的值作为其参数。也就是说，我们可以在调用<code>panic</code>函数的时候可以传入任何类型的值。不过，我建议大家在这里只传入<code>error</code>类型的值。这样它表达的语义才是精确的。更重要的是，当我们调用<code>recover</code>函数来“恢复”由于调用<code>panic</code>函数而引发的运行时恐慌的时候，得到的值正是调用后者时传给它的那个参数。因此，有这样一个约定是很有必要的。</p>
<p>用法</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<h2 id="go语句">go语句</h2>
<p><code>go</code>语句的执行会很快结束，并不会对当前流程的进行造成阻塞或明显的延迟。</p>
<p>在<code>go</code>语句被执行时，其携带的函数（也被称为<code>go</code>函数）以及要传给它的若干参数（如果有的话）会被封装成一个实体（即Goroutine），并被放入到相应的待运行队列中。Go语言的运行时系统会适时的从队列中取出待运行的Goroutine并执行相应的函数调用操作。注意，对传递给这里的函数的那些参数的求值会在<code>go</code>语句被执行时进行。这一点也是与<code>defer</code>语句类似的。</p>
<p>由于<code>go</code>函数的执行时间的不确定性，所以Go语言提供了很多方法来帮助我们协调它们的执行。其中最简单粗暴的方法就是调用<code>time.Sleep</code>函数。</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>另一个比较绅士的做法是在<code>main</code>函数的最后调用<code>runtime.Gosched</code>函数。</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p><code>runtime.Gosched</code>函数的作用是让当前正在运行的Goroutine（这里是运行<code>main</code>函数的那个Goroutine）暂时“休息”一下，而让Go运行时系统转去运行其它的Goroutine（这里是与<code>go fmt.Println(&quot;Go!&quot;)</code>对应并会封装<code>fmt.Println(&quot;Go!&quot;)</code>的那个Goroutine）。如此一来，我们就更加精细地控制了对几个Goroutine的运行的调度。</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p><code>sync.WaitGroup</code>类型有三个方法可用——<code>Add</code>、<code>Done</code>和<code>Wait</code>。<code>Add</code>会使其所属值的一个内置整数得到相应增加，<code>Done</code>会使那个整数减<code>1</code>，而<code>Wait</code>方法会使当前Goroutine（这里是运行<code>main</code>函数的那个Goroutine）阻塞直到那个整数为``。这下你应该明白上面这个示例所采用的方法了。我们在<code>main</code>函数中启用了三个Goroutine来封装三个<code>go</code>函数。每个匿名函数的最后都调用了<code>wg.Done</code>方法，并以此表达当前的<code>go</code>函数会立即执行结束的情况。当这三个<code>go</code>函数都调用过<code>wg.Done</code>函数之后，处于<code>main</code>函数最后的那条<code>wg.Wait()</code>语句的阻塞作用将会消失，<code>main</code>函数的执行将立即结束。</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<blockquote>
</blockquote>

    </article>
  </div>

  
  
  

  
</body>

</html>